﻿using Fast;
using Fast.Extensions.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using System;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    /// JwtBearer服务扩展类
    /// </summary>
    public static class JwtBearerServiceCollectionExtensions
    {
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="jwtBearerConfigure"></param>
        /// <param name="enableGlobalAuthorize"></param>
        /// <returns></returns>
        private static AuthenticationBuilder AddJwt(
            this AuthenticationBuilder builder,
            Action<JwtBearerOptions> jwtBearerConfigure, 
            bool enableGlobalAuthorize = false
        )
        {
            builder.Services.AddConfigureOptions<JwtParametersOptions>();
            builder.Services.AddSingleton<ITokenService, JwtTokenService>();
            builder.AddJwtBearer(options =>
            {
                var tokenService = App.ServicesProvider.GetService<ITokenService>();
                //设置Token参数配置
                options.TokenValidationParameters = tokenService.TokenValidationParameters;

                jwtBearerConfigure?.Invoke(options);
            });

            if (enableGlobalAuthorize)
            {
                builder.Services.Configure<MvcOptions>(options => { options.Filters.Add(new AuthorizeFilter()); });
            }

            return builder;
        }

        /// <summary>
        /// 添加Bearer认证
        /// </summary>
        /// <param name="services"></param>
        /// <param name="authenticationConfigure"></param>
        /// <param name="jwtBearerConfigure"></param>
        /// <returns></returns>
        public static IServiceCollection AddJwtWithBearerAuthentication(this IServiceCollection services,
            Action<AuthenticationOptions> authenticationConfigure = null,
            Action<JwtBearerOptions> jwtBearerConfigure = null)
        {
            //添加认证相关服务并配置认证方案
            var authenticationBuilder = services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

                authenticationConfigure?.Invoke(options);
            });
            //添加Bearer认证
            authenticationBuilder.AddJwt(jwtBearerConfigure);

            return services;
        }

        /// <summary>
        /// 添加Bearer认证并携带策略授权
        /// </summary>
        /// <typeparam name="TAuthorizationHandler">策略授权处理器</typeparam>
        /// <param name="services"></param>
        /// <param name="authenticationConfigure"></param>
        /// <param name="jwtBearerConfigure"></param>
        /// <param name="enableGlobalAuthorize"></param>
        /// <returns></returns>
        public static IServiceCollection AddJwtWithBearerAuthentication<TAuthorizationHandler>(
            this IServiceCollection services,
            Action<AuthenticationOptions> authenticationConfigure = null,
            Action<JwtBearerOptions> jwtBearerConfigure = null,
            bool enableGlobalAuthorize = false
        ) where TAuthorizationHandler : class, IAuthorizationHandler
        {
            // 添加策略授权服务
            services.AddFastAuthorization<TAuthorizationHandler>(enableGlobalAuthorize: enableGlobalAuthorize);

            // 添加授权
            return services.AddJwtWithBearerAuthentication(authenticationConfigure, jwtBearerConfigure);
        }
    }
}